/*
 * Copyright (c) Jiandong.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import hilog from '@ohos.hilog';
import http from '@ohos.net.http';

import { PackagerStatusCallback } from './PackagerStatusCallback';

export class PackagerStatusCheck {
  private static readonly TAG = "PackagerStatusCheck";
  private static readonly PACKAGER_OK_STATUS = "packager-status:running";
  private static readonly HTTP_CONNECT_TIMEOUT_MS = 5000;
  private static readonly HTTP_CONNECT_READ_TIMEOUT_MS = 5000;
  private static readonly PACKAGER_STATUS_URL_TEMPLATE = "http://%s/status";
  private readonly mRequest: http.HttpRequest;
  private readonly mOptions: http.HttpRequestOptions;

  public constructor(request?: http.HttpRequest, options?: http.HttpRequestOptions) {
    if (!options) {
      this.mOptions = {
        method: http.RequestMethod.GET,
        connectTimeout: PackagerStatusCheck.HTTP_CONNECT_TIMEOUT_MS, // 60000
        readTimeout: PackagerStatusCheck.HTTP_CONNECT_READ_TIMEOUT_MS, // 60000
      }
    }

    //if (!request) {
      this.mRequest = http.createHttp();
//    } else {
//      this.mRequest = request;
//    }
  }

  private static createPackagerStatusURL(host: string): string {
    //  return String.format(Locale.US, PackagerStatusCheck.PACKAGER_STATUS_URL_TEMPLATE, host);
    return `http://${host}/status`
  }

  public run(host: string, callback: PackagerStatusCallback): void {

    let statusURL: string = PackagerStatusCheck.createPackagerStatusURL(host != ''? host: "localhost:8081");
    hilog.info(0x0, PackagerStatusCheck.TAG, "statusURL: " + statusURL);
    this.mRequest.request(statusURL, this.mOptions, (err, data) => {
      if (!err) {
        // data.result contains the HTTP response. Parse the response based on service requirements.
//        console.info('Result:' + data.result);
//        console.info('code:' + data.responseCode);
//        // data.header contains the HTTP response header. Parse the content based on service requirements.
//        console.info('header:' + JSON.stringify(data.header));
//        console.info('cookies:' + data.cookies); // 8+

        let responseCode: number = data.responseCode
        if (responseCode < 200 || responseCode > 299) {
          hilog.error(0x0, PackagerStatusCheck.TAG, "Got non-success http code from packager when requesting status: " + data.responseCode);
          callback.onPackagerStatusFetched(false);
          return;
        }

        let body = data.result;
        if (body == null || body == undefined) {
          hilog.error(0x0, PackagerStatusCheck.TAG, "Got null body response from packager when requesting status");
          callback.onPackagerStatusFetched(false);
          return;
        }
        let bodyString: string
        if (typeof data.result == 'string') {
          bodyString = data.result as string
        }
        // https://github.com/square/okhttp/issues/1240#issuecomment-68142603
        if (PackagerStatusCheck.PACKAGER_OK_STATUS != bodyString) {
          hilog.error(0x0, PackagerStatusCheck.TAG, "Got unexpected response from packager when requesting status: " + bodyString);
          callback.onPackagerStatusFetched(false);
          return;
        }
        callback.onPackagerStatusFetched(true);
      } else {
        console.info('error:' + JSON.stringify(err));
        hilog.warn(0x0, PackagerStatusCheck.TAG,
          "The packager does not seem to be running as we got an IOException requesting, its status: %{public}s", err.message);
        callback.onPackagerStatusFetched(false);
        this.mRequest.destroy();
      }
    });
  }
}
